#include "LRTableBuilder.hpp"

std::unordered_map<std::string, std::unordered_set<std::string>>
LRTableBuilder::getFollowSet(std::vector<define> defineVec,
                             const std::unordered_set<std::string> &terminals) {
  LL1Parser ll1parser;
  ll1parser.defines = defineVec;
  ll1parser.terminals = terminals;
  return ll1parser.get_follow_set();
}

LRTable LRTableBuilder::buildTableFrom(
    const std::vector<ProjectSet> &pjSetVec,
    const std::vector<DefineExpr> &defineExpresses,
    std::unordered_map<std::string, std::unordered_set<std::string>>
        followSet) {
  std::unordered_map<std::string, TableItem> table;
  for (int i = 0; i < pjSetVec.size(); ++i) {
    std::string i_str = std::to_string(i);
    for (const auto &kv : pjSetVec[i].itemKVs) {
      const auto defineExprIndex = kv.second.defineExprIndex;
      const auto &rightItem = defineExpresses[defineExprIndex].rightItem;
      const auto &leftItem = defineExpresses[defineExprIndex].leftItem;
      // printf("%d %d %d\n", i, rightItem.size(), kv.second.pointPos);
      if (rightItem.size() == kv.second.pointPos ||
          rightItem.front() == "") { // 点在最后
        for (auto &item : followSet[leftItem]) {
          table[i_str + item] = TableItem{true, defineExprIndex};
        }
      }
    }
    for (const auto &item : pjSetVec[i].convertion) {
      table[i_str + item.first] = TableItem{false, item.second};
    }
  }

  LRTable res;
  res.table = table;
  return res;
}
